home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’96
/
Better AD security
/
Source
/
ShowIcon.c
< prev
next >
Wrap
Text File
|
1996-06-21
|
8KB
|
340 lines
/* NAME:
ShowIcon.c
WRITTEN BY:
Dair Grant, based on Peter Lewis/Jim Walker/François Pottier/
previous ShowINIT authors' work.
DESCRIPTION:
This code is based on various bits of icon drawing code, and
adapted to support animated icons.
NOTES:
We use the System 7 IconSuite calls to display the appropriate icon
from our INIT code's icon family. This looks after bit depths, and
removes the need for 'cicn's for colour displays.
If we can't use the IconSuite routines, we can only handle 'ICN#'
resources.
___________________________________________________________________________
*/
//=============================================================================
// Include files
//-----------------------------------------------------------------------------
#include <Resources.h>
#include <Icons.h>
#include "ES.h"
#include "ShowIcon.h"
//=============================================================================
// Private function prototypes
//-----------------------------------------------------------------------------
unsigned short CheckSum(unsigned short x);
void GetIconRect(Rect *theRect, Rect *thePortRect);
void NextPosition(Rect *theRect);
void PlotBWIcon(Rect *iconRect, Handle theIcon);
//=============================================================================
// Private defines
//-----------------------------------------------------------------------------
#define LMVCoord (* (short*) 0x92A) // Vertical coordinate
#define LMVCheckSum (* (short*) 0x928) // Vertical coordinate checksum
#define LMHCoord (* (short*) 0x92C) // Horizontal coordinate
#define LMHCheckSum (* (short*) 0x92E) // Horizontal coordinate checksum
//=============================================================================
// PlotINITIcon : Plot a series of icons on the screen.
//-----------------------------------------------------------------------------
// Note : We are passed an array of icon resource IDs, the number of
// valid IDs there are in the array, the number of ticks to wait
// between showing each icon, and a status flag for the presence
// of Color Quickdraw and the IconSuite routines.
//
// Usually Extensions will pass in only one icon, but this allows
// us to support animated icons as well.
//
// We use the _IconSuite routines to plot the icons. These
// look after all the details of deciding what icon to use,
// depending on the depth of the display. They also work using
// the same icon families that the Finder uses, which means
// there's no need for a 'cicn' version.
//
// If we don't have _IconSuite, or Colour QuickDraw, we have to
// plot an 'ICN#' icon.
//-----------------------------------------------------------------------------
void PlotINITIcon(Boolean useIconSuite, short animDelay, short numIcons, short (*theIcons)[])
{ GrafPtr savePort, newPort;
GrafPort newBWPort;
CGrafPort newColourPort;
Handle theIconHnds[kMaxNumIcons+1];
Rect theIconPos;
long theTicks;
short i;
// Save the port, and open a new one
GetPort(&savePort);
if (useIconSuite)
{
OpenCPort(&newColourPort);
newPort = (GrafPtr) &newColourPort;
}
else
{
OpenPort(&newBWPort);
newPort = &newBWPort;
}
SetPort(newPort);
// Work out where we should draw the icon
GetIconRect(&theIconPos, &newPort->portRect);
// Read in handles to as many icons as we have to/can. If we Get/Plot/Dispose
// of each icon in turn, we can get jerky animation.
for (i = 1; i <= numIcons && i <= kMaxNumIcons; i++)
{
if (useIconSuite)
GetIconSuite(&theIconHnds[i], (*theIcons)[i], svAllLargeData);
else
theIconHnds[i] = GetResource('ICN#', (*theIcons)[i]);
}
// Plot all the icons, with the right delay
for (i = 1; i <= numIcons && i <= kMaxNumIcons; i++)
{
if (useIconSuite)
PlotIconSuite(&theIconPos, atNone, ttNone, theIconHnds[i]);
else
PlotBWIcon(&theIconPos, theIconHnds[i]);
Delay(animDelay, &theTicks);
}
// Before releasing them again
for (i = 1; i <= numIcons && i <= kMaxNumIcons; i++)
{
if (useIconSuite)
DisposeIconSuite(theIconHnds[i], true);
else
ReleaseResource(theIconHnds[i]);
}
// Set things up for the next INIT's icon - if we drew anything
if (numIcons > 0)
NextPosition(&theIconPos);
// Dispose of our temporary port, and restore the old one
if (useIconSuite)
CloseCPort(&newColourPort);
else
ClosePort(&newBWPort);
SetPort(savePort);
}
//=============================================================================
// CheckSum : Verify that the previous INIT knew about ShowINIT Icon.
//-----------------------------------------------------------------------------
unsigned short CheckSum(unsigned short x)
{
return((x << 1) | (x >> 15)) ^ 0x1021;
}
//=============================================================================
// GetIconRect : Calculate the correct position for our INIT's icon.
//-----------------------------------------------------------------------------
// Note : We leave the correct position in theRect. We are given the
// portRect field of the current graphics port in thePortRect.
//
// *theRect is forced to be onscreen. This is done by taking
// the horizontal offset modulo the screen width to generate the
// horizontal position of the icon, and the offset divided by the
// screen width to generate the proper row. This mechanism can get
// messed up if people plot icons at non-standard offsets.
//
// We are also responsible for initialising the ShowInitIcon
// mechanism if we're the first INIT to load.
//-----------------------------------------------------------------------------
void GetIconRect(Rect *theRect, Rect *thePortRect)
{
// If we're first, initialise the mechanism for everyone else
if (CheckSum(LMHCoord) != LMHCheckSum)
LMHCoord = 8;
if (CheckSum(LMVCoord) != LMVCheckSum)
LMVCoord = thePortRect->bottom - 40;
// Wrap round if we would move off the edge of the screen
if (LMHCoord + 34 > thePortRect->right)
{
theRect->left = 8;
theRect->top = LMVCoord - 40;
}
// Otherwise move ourselves to the next position
else
{
theRect->left = LMHCoord;
theRect->top = LMVCoord;
}
theRect->right = theRect->left + 32;
theRect->bottom = theRect->top + 32;
}
//=============================================================================
// NextPosition : Advance the ShowIcon position for the next INIT.
//-----------------------------------------------------------------------------
void NextPosition(Rect *theRect)
{
// Update the position for the next INIT
LMHCoord = theRect->left + 40;
LMVCoord = theRect->top;
LMHCheckSum = CheckSum(LMHCoord);
LMVCheckSum = CheckSum(LMVCoord);
}
//=============================================================================
// PlotBWIcon : Plot an 'ICN#' icon.
//-----------------------------------------------------------------------------
void PlotBWIcon(Rect *iconRect, Handle theIcon)
{ BitMap src;
GrafPtr thePort;
// Lock the icon down, if we have one
if (theIcon == nil)
return;
else
HLock(theIcon);
// Prepare the source and destination bitmaps
src.baseAddr = *theIcon + 128; // 128 byte ofset to Mask
src.rowBytes = 4;
SetRect(&src.bounds, 0, 0, 32, 32);
GetPort(&thePort);
// Transfer the mask
CopyBits(&src, &thePort->portBits, &src.bounds, iconRect, srcBic, nil);
// Followed by the icon
src.baseAddr = *theIcon; // 0 byte offset to icon data
CopyBits(&src, &thePort->portBits, &src.bounds, iconRect, srcOr, nil);
// Unlock the icon
HUnlock(theIcon);
}